package com.yang.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.yang.domain.Car;
import com.yang.domain.User;
import com.yang.domain.UserCarDetails;
import com.yang.handler.UserThreadLocal;
import com.yang.service.CarService;
import com.yang.service.UserCarDetailsService;
import com.yang.utils.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import static com.yang.controller.UserController.checkIsAdmin;

/**
 * 车辆Controller
 *
 * @author 不是菜鸡爱编程
 * @date 2024-02-18
 */
@Slf4j
@RestController
@RequestMapping("/car")
@Api(tags = "车辆模块", value = "车辆Controller")
public class CarController {
    @Autowired
    private CarService carService;
    @Autowired
    private UserCarDetailsService userCarDetailsService;

    /**
     * 查询车辆列表
     */
    @ApiOperation("查询车辆列表")
    @GetMapping("/list")
    public R list(Car car, @RequestParam Integer pageNum, @RequestParam Integer pageSize) {
        LambdaQueryWrapper<Car> wrapper = new LambdaQueryWrapper<Car>()
                .eq(ObjUtil.isNotEmpty(car.getCard()), Car::getCard, car.getCard())
                .eq(ObjUtil.isNotEmpty(car.getTypes()), Car::getTypes, car.getTypes())
                .eq(ObjUtil.isNotEmpty(car.getBrand()), Car::getBrand, car.getBrand())
                .eq(ObjUtil.isNotEmpty(car.getDelFlag()), Car::getDelFlag, car.getDelFlag());
        // 如果是普通用户，则只能查询到逻辑删除列为0的数据【且只能查询到自己的车辆信息】
        // 管理员则可以查询到全部的车辆信息
        User user = UserThreadLocal.get();
        boolean checkIsAdmin = user.getIsAdmin()==0;
        if (!checkIsAdmin) {
            wrapper.eq(Car::getDelFlag, 0);
            // 普通用户只能查询到自己的车辆信息
            List<String> carCard = userCarDetailsService.listObjs(new LambdaQueryWrapper<UserCarDetails>()
                    .select(UserCarDetails::getCarCard)
                    .eq(UserCarDetails::getUserId, user.getId()), Object::toString);
            // 如果车主名下没有车辆，则直接返回空
            if(!CollUtil.isNotEmpty(carCard)){
                return R.ok().setData(new Page<>(pageNum, pageSize));
            }else{
                wrapper.in(Car::getCard, carCard);
            }
        }
        // 查询到全部车辆信息
        IPage<Car> page = carService.page(new Page<>(pageNum, pageSize), wrapper);
        return R.ok().setData(page);
    }

    /**
     * 获取车辆详细信息
     */
    @ApiOperation("获取车辆详细信息")
    @GetMapping(value = "/{card}")
    public R getInfo(@PathVariable("card") String card) {
        MPJLambdaWrapper<Car> wrapper = new MPJLambdaWrapper<Car>()
                .selectAll(Car.class)
                // 将用户信息映射到userList字段上
                .selectCollection(User.class, Car::getUserList)
                .leftJoin(UserCarDetails.class, UserCarDetails::getCarCard, Car::getCard)
                .leftJoin(User.class, User::getId, UserCarDetails::getUserId)
                .eq(Car::getCard, card);
        // 如果是普通用户，则只能查询到逻辑删除列为0的数据
        if (checkIsAdmin()!=0) {
            wrapper.eq(User::getDelFlag, 0);
        }
        return R.ok().setData(carService.selectJoinOne(Car.class, wrapper));
    }

    /**
     * 新增车辆
     */
    @ApiOperation("新增车辆")
    @PostMapping
    public R add(@RequestBody Car car) {
        // 查询车牌号是否已经存在
        long countCard = carService.count(new LambdaQueryWrapper<Car>().eq(Car::getCard, car.getCard()));
        if(countCard>0){
            return R.error("车牌号已经存在");
        }
        User currentUser = UserThreadLocal.get();
        car.setCreateBy(currentUser.getId());
        car.setUpdateBy(currentUser.getId());
        ArrayList<UserCarDetails> userCarDetails = new ArrayList<>();
        List<User> userList = car.getUserList();
        // 如果是普通用户
        if(currentUser.getIsAdmin()==1){
            // 绑定当前用户信息
            userCarDetailsService.save(new UserCarDetails(currentUser.getId(),car.getCard()));
        }else{
            // 如果更新后绑定的用户信息不为空
            if(CollUtil.isNotEmpty(userList)){
                // 则收集用户id
                for (User user : userList) {
                    userCarDetails.add(new UserCarDetails(user.getId(),car.getCard()));
                }
            }
        }
        userCarDetailsService.saveBatch(userCarDetails);
        return R.ok().setData(carService.save(car));
    }

    /**
     * 修改车辆
     */
    @ApiOperation("修改车辆")
    @PutMapping
    public R edit(@RequestBody Car car) {
        ArrayList<UserCarDetails> userCarDetails = new ArrayList<>();
        List<User> userList = car.getUserList();
        // 如果更新后绑定的用户信息不为空
        if(CollUtil.isNotEmpty(userList)){
            // 则收集用户id
            for (User user : userList) {
                userCarDetails.add(new UserCarDetails(user.getId(),car.getCard()));
            }
        }
        MPJLambdaWrapper<Car> wrapper = new MPJLambdaWrapper<Car>()
                .selectAll(Car.class)
                // 将用户信息映射到userList字段上
                .selectCollection(User.class, Car::getUserList)
                .leftJoin(UserCarDetails.class, UserCarDetails::getCarCard, Car::getCard)
                .leftJoin(User.class, User::getId, UserCarDetails::getUserId)
                .eq(Car::getCard, car.getCard());
        // 如果是普通用户，则只能查询到逻辑删除列为0的数据
        if (checkIsAdmin()!=0) {
            wrapper.eq(User::getDelFlag, 0);
        }
        // 更新前的车辆包括关联信息
        Car beforeUpdateCar = carService.selectJoinOne(Car.class, wrapper);
        List<User> beforeUpdateUserList = beforeUpdateCar.getUserList();
        // 判断关联信息是否更新过
        if(!beforeUpdateUserList.equals(userList)){
            // 更新过关联信息
            userCarDetailsService.remove(new LambdaQueryWrapper<UserCarDetails>()
                    .eq(UserCarDetails::getCarCard,car.getCard())
                    .in(CollUtil.isNotEmpty(beforeUpdateUserList),
                            UserCarDetails::getUserId,
                            // 收集更新前的绑定的用户id
                            beforeUpdateUserList.stream().map(User::getId).collect(Collectors.toList())));
            userCarDetailsService.saveBatch(userCarDetails);
        }
        carService.update(car, new LambdaQueryWrapper<Car>()
                .eq(Car::getCard, car.getCard()));
        return R.ok();
    }

    /**
     * 删除车辆
     */
    @ApiOperation("删除车辆")
    @DeleteMapping("/{cards}")
    public R remove(@PathVariable String[] cards) {
        return R.ok().setData(carService.update(null, new LambdaUpdateWrapper<Car>()
                .set(Car::getDelFlag, 1)
                .in(Car::getCard, Arrays.asList(cards))));
    }

    @ApiOperation("查询车辆列表")
    @GetMapping("/listAll")
    public R listAll() {
        return R.ok().setData(carService.list());
    }
}
